package pe.com.pgn.consolidadorventas.servidorcentral.util;

import java.net.URL;
import java.util.List;

import javax.xml.soap.MessageFactory;
import javax.xml.soap.Name;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPBodyElement;
import javax.xml.soap.SOAPConnection;
import javax.xml.soap.SOAPConnectionFactory;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPMessage;
import javax.xml.soap.SOAPPart;

import org.apache.log4j.Logger;
import org.w3c.dom.NodeList;

public class MessengerSOAP {

	static Logger logger = Logger.getLogger(MessengerSOAP.class);

	String protocolo;
	String ip;
	String puerto;
	String contexto;
	String webservice;
	String namespace;
	String ruta;
	boolean llamadaCancelada;
	
	/*Valores para conexion*/
    SOAPConnectionFactory soapConnFactory;
    SOAPConnection connection;
    MessageFactory messageFactory;
    SOAPMessage message;     
    SOAPPart soapPart;
    SOAPEnvelope envelope;
    
    /*Cabecera SOAP*/
    SOAPHeader header;
    SOAPElement security;
    SOAPElement usernameToken;
    SOAPElement username;
    SOAPElement password;
    SOAPElement nonce;
    int usarCifrado;
    
    /*Mensaje SOAP*/
    SOAPBody body;
    Name bodyName;
    SOAPBodyElement bodyElement;
    SOAPElement symbol;
      
    public MessengerSOAP(String protocolo, 
    					 String ip, 
    					 String puerto,
    					 String contexto, 
    					 String webservice,
    					 String namespace) {
		this.protocolo = protocolo;
		this.ip = ip;
		this.puerto = puerto;
		this.contexto = contexto;
		this.webservice = webservice;
		this.namespace = namespace;
		
    	usarCifrado = 1;
    	llamadaCancelada = false;
    }

	public MessengerSOAP(){
    	usarCifrado = 1;
    }
	
	public void inicializarRutaConexion(){
		ruta = protocolo + "://" + ip + ":" + puerto + "/" + contexto + "/" + webservice;
		try{
			 soapConnFactory = SOAPConnectionFactory.newInstance();
             connection =  soapConnFactory.createConnection();
            
             messageFactory = MessageFactory.newInstance();
             message = messageFactory.createMessage();
             
             //Creamos objetos SOAP          
             soapPart = message.getSOAPPart();
             envelope = soapPart.getEnvelope();
             
		}catch(SOAPException e){
			LoggerUtil.error(logger,e.getMessage());
		}
	}
	
	public void inicializarCabeceraMensaje(String usuario,String clave){
    	//Para implementar despues		
		try{
		    header = envelope.getHeader();
	        security =header.addChildElement("Security", "wsse", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");

	        usernameToken =security.addChildElement("UsernameToken", "wsse");

	        username = usernameToken.addChildElement("Username", "wsse");
	        username.addTextNode(usuario);  //seteamos el usuario

	        password = usernameToken.addChildElement("Password", "wsse");
	        password.setAttribute("Type", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText");
	        
	        if(usarCifrado == 1){
	        	password.addTextNode(SHA1.getHash(clave));
	        }else{
		        password.addTextNode(clave); //seteamos la clave
	        }

		}catch(SOAPException e){
			LoggerUtil.error(logger,"Excepcion al inicializar cabecera"+e.getMessage());
		}
    }
	
	public void inicializarCuerpoMensaje(String nombreFuncionWebService,List<String> parametrosWs,List<String> valoresParametrosWs){
		try{
		    body  = envelope.getBody();
		    
		    //Asignamos el nombre de la funcion
	        bodyName = envelope.createName(nombreFuncionWebService,"ns1", namespace);
	        bodyElement = body.addBodyElement(bodyName);
	        
	        //Agregamos los parametros
	        int dim = parametrosWs.size();
	        int i = 0;
	        Name aux = null;
	        while(i<dim){
	        	aux = envelope.createName(parametrosWs.get(i));
		        symbol = bodyElement.addChildElement(aux);
		        symbol.addTextNode(valoresParametrosWs.get(i));
		        i++;
	        }
	        
		}catch(SOAPException e){
			LoggerUtil.error(logger,"Excepcion al inicializar cuerpo :"+e.getMessage());
		}
	}
	
	public String enviarMensaje(String tagRespuesta){
		
		String rpta="-1";
		try{
				 message.saveChanges();

			     //Creamos la url con la ruta
			     URL endpoint = new URL(ruta);
			    
			     //Enviamos el mensaje
			     LoggerUtil.info(logger,"Inicia Conexion Ws");
			     SOAPMessage reply = connection.call(message,endpoint);  
			    
		         //Imprimiendo el valor
			     SOAPPart part = reply.getSOAPPart();
			     SOAPEnvelope envelopeMensaje=part.getEnvelope();
			
			     //////////////////////
		         SOAPBody cuerpoMensaje=envelopeMensaje.getBody();
		         
		         //Leemos el tag que contiene la respuesta
		         NodeList lista=cuerpoMensaje.getElementsByTagName(tagRespuesta);
		         if(lista==null){
		        	 if(!llamadaCancelada){
		        		LoggerUtil.debug(logger,"No Hubo respuesta Ws");
		        	 }
		         }else{
		        	 rpta=lista.item(0).getTextContent();
		         } 
		         connection.close();
		         
		         if(!llamadaCancelada){
		        	LoggerUtil.info(logger,"Fin Conexion Ws"); 
		         }

		}catch(Exception e){
			if(!llamadaCancelada){
				LoggerUtil.error(logger,"Excepcion al enviar mensaje ( "+ip+":"+puerto+" ) :"+e.getMessage());
			}
		}
		
		return rpta;
	}

	public int getUsarCifrado() {
		return usarCifrado;
	}

	public void setUsarCifrado(int usarCifrado) {
		this.usarCifrado = usarCifrado;
	}
	
	public void cancelarLlamada(){
		this.llamadaCancelada = true;
	}
   
}
